package com.example.flowable.holiday;

import org.flowable.engine.*;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.task.Comment;
import org.flowable.task.api.Task;

import java.util.*;

/**
* 此类描述的是：测试demo
* 参考flowable手册https://tkjohn.github.io/flowable-userguide/
*/
public class HolidayRequest {
    public static void main(String[] args) {
        extracted();
    }

    private static void extracted() {
        //1.创建了一个独立(standalone)配置
        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
                .setJdbcUrl("jdbc:mysql://192.168.0.137:3306/fwf_xyqq_flowable?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true")
                .setJdbcUsername("root")
                .setJdbcPassword("123456")
                .setJdbcDriver("com.mysql.jdbc.Driver")
                //如果数据表不存在的时候，自动创建数据表
                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);

        //2.创建流程引擎
        ProcessEngine processEngine = cfg.buildProcessEngine();

        //3.利用流程引擎部署流程
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment deployment = repositoryService.createDeployment().addClasspathResource("holiday-request.bpmn20.xml").deploy();

        //4.根据流程部署实例id获取流程定义实例
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
        System.out.println("processDefinitionName : " + processDefinition.getName());

        //5.启动process实例
        String employee = "zhansan";
        Integer nrOfHolidays = 5;
        String description = "hahaha";
        //5.1.2 此处代码类似web后端获取前端表单传来的字段
        Map<String, Object> variables = new HashMap<>();
        variables.put("employee", employee);
        variables.put("nrOfHolidays", nrOfHolidays);
        variables.put("description", description);
        variables.put("approved", true);
        variables.put("breakPoints", Arrays.asList("approveTask", "decision",  "externalSystemCall", "holidayApprovedTask", "sendRejectionMail"));

        //6.发起流程
        RuntimeService runtimeService = processEngine.getRuntimeService();
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holidayRequest", variables);

        //7.经理查询待办任务
        TaskService taskService = processEngine.getTaskService();
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("managers").list();

        //8.经理处理审批任务
        for (int i=0; i<tasks.size(); i++) {
            System.out.println((i+1) + ") " + tasks.get(i).getName());
        }
        //8.1 选择要处理的任务
        Task task = tasks.get(0);

        //8.3 对前端传来的审批意见进行保存
        if (true){
            Comment comment = taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), "同意休假");
            comment.setUserId("manager");
            taskService.saveComment(comment);
        }else{
            Comment comment = taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), "不允许休假");
            comment.setUserId("manager");
            taskService.saveComment(comment);
        }
        //8.4 完成任务
        taskService.complete(task.getId(), variables);

        //注意发起流程时的employee，最好为申请人或者审批人的id或其他唯一字段
        tasks = taskService.createTaskQuery().taskAssignee(employee).list();
        //10.申请人处理休假任务
        System.out.println("You have " + tasks.size() + " tasks:");
        for (int i=0; i<tasks.size(); i++) {
            System.out.println((i+1) + ") " + tasks.get(i).getName());
        }
        if (tasks.size() > 0){
            System.out.println("Which task would you like to complete?");
            //10.1 选择要处理的任务
            task = tasks.get(0);
            //使用任务Id获取特定流程实例的变量
            Map<String, Object> processVariables = taskService.getVariables(task.getId());
            //10.2 保存前端传来的审批意见
            Comment comment1 = taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), processVariables.get("employee") + "休假中");
            comment1.setUserId("employe");
            taskService.saveComment(comment1);
            //10.3 完成任务
            taskService.complete(task.getId(), variables);
        }
        //展示审批意见
        List<Comment> taskComments = taskService.getProcessInstanceComments(processInstance.getProcessInstanceId());
        for (Comment comment:taskComments){
            System.out.println("审批人："+comment.getUserId()+ ",审批意见：" + comment.getFullMessage() + ",审批时间：" + comment.getTime());
        }
    }
}
